package org.apache.ocean.main.util;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

import org.apache.ocean.main.util.Timeout.TimeoutException;

/**
 *
 * @author jasonr
 */
public class RefWaitNotNull<V> {
  private V object;
  private ReentrantLock lock = new ReentrantLock();
  private Condition notNullCondition = lock.newCondition();

  public RefWaitNotNull() {
  }
  
  public boolean isNull() {
  	return object == null;
  }
  
  public boolean isNotNull() {
  	return object != null;
  }
  
  public V getNoWait() {
    return object;
  }

  public void set(V object) {
    lock.lock();
    try {
      this.object = object;
      if (object != null) {
        notNullCondition.signalAll();
      }
    } finally {
      lock.unlock();
    }
  }

  public V get() throws InterruptedException {
    if (object != null) {
      return object;
    }
    lock.lock();
    try {
      notNullCondition.await();
      return object;
    } finally {
      lock.unlock();
    }
  }

  public V get(Timeout timeout) throws TimeoutException, InterruptedException {
    if (object != null) {
      return object;
    }
    lock.lock(); 
    try {
      notNullCondition.await(timeout.getTimeLeft(), TimeUnit.MILLISECONDS);
      if (object == null) throw new TimeoutException(timeout);
      return object;
    } finally {
      lock.unlock();
    }
  }
}
